package org.thunms.framework.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;
import org.thunms.framework.io.FileUtils;
import org.thunms.framework.io.IOUtils;
import org.thunms.framework.io.LineRead;

/**
 * Java中调用操作系统命令方法的
 */
public class UtilProcess {
	
	
	public static int exec(String command){
        return exec(command, null,null,null,null);
    }
	public static int exec(String command, String[] envp){
        return exec(command, envp, null,null);
    }
	public static int exec(String command, String[] envp, File dir){
	    	return exec(command, envp, dir, null);
	    	
	}
	public static int exec(String cmdarray[]){
    	return exec(cmdarray, null,null,null,null);
    }
	
	public static int exec(String[] cmdarray, String[] envp){
	    	return exec(cmdarray, envp, null,null);
	}
	
	 public static int exec(String[] cmdarray, String[] envp, File dir){
	    	return exec(cmdarray, envp, dir, null);
	 }
	
	public static int exec(String command,String logPath){
        return exec(command, null, null,logPath,null,null);
    }
   
    public static int exec(String command, String[] envp,String logPath){
        return exec(command, envp, null,logPath,null,null);
    }
    
    public static int exec(String command, String[] envp, File dir,String logPath){
    	return exec(command, envp, dir, logPath, null, null);
    }
    
    
    public static int exec(String cmdarray[],String logPath){
    	return exec(cmdarray, logPath, null, null);
    }
    
    public static int exec(String[] cmdarray, String[] envp,String logPath){
    	return exec(cmdarray, envp, logPath, null, null);
    }
   
    public static int exec(String[] cmdarray, String[] envp, File dir,String logPath){
    	return exec(cmdarray, envp, dir, logPath, null, null);
    }
    
    public static int exec(String command,String logPath,String processKey,Map<String,Process> process){
        return exec(command, null, null,logPath,processKey,process);
    }
    public static int exec(String command, String[] envp,String logPath,String processKey,Map<String,Process> process){
        return exec(command, envp, null,logPath,processKey,process);
    }
    public static int exec(String cmdarray[],String logPath,String processKey,Map<String,Process> process){
        return exec(cmdarray, null, null,logPath,processKey,process);
    }
    public static int exec(String[] cmdarray, String[] envp,String logPath,String processKey,Map<String,Process> process){
         return exec(cmdarray, envp, null,logPath,processKey,process);
    }
    
    public static int exec(String command, String[] envp, File dir,String logPath,String processKey,Map<String,Process> process){
        if (command.length() == 0)
            throw new IllegalArgumentException("Empty command");

        StringTokenizer st = new StringTokenizer(command);
        String[] cmdarray = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++)
            cmdarray[i] = st.nextToken();
        return exec(cmdarray, envp, dir,logPath,processKey,process);
    }
   
    public static int exec(String[] cmdarray, String[] envp, File dir,String logPath,String processKey,Map<String,Process> process){
		Process p =null;
		int res=-1;
		try {
			List<StreamGobbler> tasks=new ArrayList<StreamGobbler>(2);
			p=Runtime.getRuntime().exec(cmdarray,envp,dir);
			if(StringUtils.isNotBlank(processKey)&&process!=null){
				process.put(processKey, p);
			}
			
			StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), logPath);
			StreamGobbler outGobbler = new StreamGobbler(p.getInputStream(), logPath);
			tasks.add(errorGobbler);
			tasks.add(outGobbler);
	        errorGobbler.start();
	        outGobbler.start();
	        for (StreamGobbler t : tasks) {
				t.join();
			}
			
			p.waitFor();
		} catch (Exception e) {
			
		}finally{
			if(p!=null){
				p.destroy();
			}
			if(StringUtils.isNotBlank(processKey)&&process!=null){
				process.remove(processKey);
			}
		}
		return res;
		
    }
    
    private static class StreamGobbler extends Thread {  
       private  InputStream is;  
        private File logs=null;
              
        StreamGobbler(InputStream is, String logPath) {  
            this.is=is;
            if(StringUtils.isNotBlank(logPath)){
            	logs=new File(logPath);
            }
        }  
      
         
          
        public void run() { 
            try {  
                if (is != null)  
                {
                	if(UtilOSinfo.isWindows()){
                		IOUtils.readLines(is, "GBK",new LineRead() {
    						private static final long serialVersionUID = 5143947224000536746L;
    						@Override
    						public void read(String line) {
    							if(logs!=null){
    								try {
    									FileUtils.writeStringToFile(logs, line+"\n", "utf-8", true);
    								} catch (IOException e) {
    								}
    							}
    						}
    					});
                	}else{
                		IOUtils.readLines(is, "utf-8",new LineRead() {
    						private static final long serialVersionUID = 5143947224000536746L;
    						@Override
    						public void read(String line) {
    							if(logs!=null){
    								try {
    									FileUtils.writeStringToFile(logs, line+"\n", "utf-8", true);
    								} catch (IOException e) {
    								}
    							}
    						}
    					});
                	}
                	
                	
                } 
            } catch (IOException e) {  
                //e.printStackTrace();    
            } finally{  
               IOUtils.closeQuietly(is);  
            }  
        }  
    }   
    public static void main(String[] args) throws IOException {
		
	}
}